#include "string.h"
#include "buffer.h"


CLoopBuffer::CLoopBuffer()
{
	Reset();	
}

CLoopBuffer::~CLoopBuffer()
{

}

void CLoopBuffer::Reset()
{
	memset(_buf, 0, sizeof(_buf));
	_head = 0;
	_foot = 0;
}

bool CLoopBuffer::Add(const unsigned char* pSrc, int nCount)
{
	if (GetCapacity()<nCount)
	{
		return false;
	}
	if (_foot >= _head)
	{
		int first_copy = nCount>(B_L-_foot)?(B_L-_foot):nCount;
		memcpy(_buf+_foot, pSrc, first_copy);
		_foot = (_foot+first_copy)%B_L;
		int second_copy = nCount - first_copy;
		if (second_copy > 0)
		{
			memcpy(_buf+_foot, pSrc+first_copy, second_copy);
			_foot = (_foot+second_copy)%B_L;
		}
		return true;
	}
	else
	{
		memcpy(_buf+_foot, pSrc, nCount);
		_foot += nCount;
		return true;
	}
}

const unsigned char* CLoopBuffer::GetBuffer()
{
	return _buf+_head;
}

unsigned int CLoopBuffer::GetCapacity()
{
	if (_foot >= _head)
	{
		return B_L-(_foot-_head) - 1;
	}
	else
	{
		return _head-_foot-1;
	}
}

unsigned int CLoopBuffer::GetPayload()
{
	return B_L - 1 - GetCapacity();
}

unsigned int CLoopBuffer::GetPayload_NoRollBack()
{
	if (_foot >= _head)
	{
		return _foot - _head;
	}
	else
	{
		return B_L - _head;
	}
}

bool CLoopBuffer::ResetPayload(unsigned int nResetCount)
{
	if (nResetCount > GetPayload())
	{
		return false;
	}
	_head = (_head+nResetCount)%B_L;
	return true;
}